import BaseModule from "./BaseModel";

export default class Inject {
    static $UUIDKEY = "$UUID__"

    private readonly $objs = new Map<number, any>();

    register<T extends new () => BaseModule>(c: T) {
        
    }

    get<T>(c: new (...ages: any[]) => T): T {
        let key = Inject.$UUID(c);
        if (!this.$objs.has(key)) {
            this.$objs.set(key, new c());
        }

        return this.$objs.get(key);
    }

    recycle<T>(c: new (...ages: any[]) => T) {
        let k = Inject.$UUID_CHECK(c);
        if (k == -1 || !this.$objs.has(k)) return;
        let obj = this.$objs.get(k);
        obj["recycle"] && obj["recycle"]();
        this.$objs.delete(k);
    }

    static $UUID(o: new (...ages: any[]) => any) {
        let uid = o[this.$UUIDKEY];
        if (uid == null) {
            uid = uuid();
            Object.defineProperty(o, this.$UUIDKEY, {
                value: uid,
                configurable: false,
                writable: false,
                enumerable: true
            });
        }

        return uid;
    }

    static $UUID_CHECK(o: any) {
        let uid = o[this.$UUIDKEY];
        if (o[this.$UUIDKEY] == null) return -1;
        return uid;
    }

}

function uuid() {
    let uuid = -1;
    return function () {
        return ++uuid;
    }
}